home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-02-21 | 9.2 KB | 433 lines | [TEXT/nX^n] |
- /************************************/
- /* A sample XCMD for Hypercard */
- /* 2.0 that displays and handles */
- /* external windows and dialogs. */
- /* */
- /* Well-behaved XCMDs for HC2.0 */
- /* will respond to the ! and ? */
- /* requests by returning version*/
- /* and usage information */
- /* respectively. */
- /* */
- /* ---------------------------- */
- /* ©1991, Donald Koscheka */
- /* All Rights Reserved */
- /************************************/
-
- /*
- Project:
-
- MacTraps
- HyperXLib-- Hypercard 2.0 callback library available from
- Apple Computer, Inc.
-
- xwindoid.c (contents of listing 1)
-
- Set Project Type:
- Type == XCMD | XFCN
- Name == xwindoid
- id == -32768..32767
-
- Usage
-
- xwindoid "?" -- XCMD
- xwindoid "!"
- put the result
-
- OR -- XFCN
-
- Put xwindoid( "?" )
- Put xwindoid( "!" )
-
- Parameters:
-
- xwindoid "name", rect, style, dlgID
-
- name == the name of the window
- rect == the rect of the window
- style== dBoxProc, documentProc, palette, …
- dlgID== dialog id( modal dialogs only).
- */
-
- #include <SetUpA4.h>
- #include <string.h>
- #include <HyperXCMD.h>
-
- #ifndef NIL
- #define NIL (void *)0L
- #endif
-
- #define ETX 0x03
- #define BS 0x08
- #define TAB 0x09
- #define LF 0x0A
- #define NEWLINE 0x0D
- #define CR 0x0D
- #define LEFT_ARROW 0x1C
- #define RIGHT_ARROW 0x1D
- #define UP_ARROW 0x1E
- #define DOWN_ARROW 0x1F
-
- /* Multifinder events and masks */
- #ifndef MouseMovedEvt
- #define MouseMovedEvt 0xFA
- #endif
-
- #ifndef SuspendResumeEvt
- #define SuspendResumeEvt 0x01
- #endif
-
- #ifndef ResumeEvtMask
- #define ResumeEvtMask 0x01
- #endif
-
- #ifndef ConvertScrapMask
- #define ConvertScrapMask 0x02
- #endif
-
- #define palette 0x80
-
- pascal void HandleHCEvent( XCmdPtr pp );
- pascal Boolean modalFilter( DialogPtr dlg, EventRecord *evt, short *itemhit );
-
- void CenterWindow( WindowPtr wptr, short isFront )
- /***************************
- * Center a window in the current
- * screen port. Note: Does not
- * attempt to work with multi-screen
- * systems.
- *
- * This code is courtesy of Steve
- * Maller of Apple Computer Inc.
- * Thanks Steve.
- ***************************/
- {
- short hWindSize = wptr->portRect.right - wptr->portRect.left;
- short vWindSize = wptr->portRect.bottom - wptr->portRect.top;
- short hSize = wptr->portBits.bounds.right - wptr->portBits.bounds.left;
- short vSize = wptr->portBits.bounds.bottom - wptr->portBits.bounds.top;
-
- MoveWindow( wptr,
- ( hSize - hWindSize ) / 2,
- ( vSize - vWindSize + 20) / 2,
- isFront
- );
- }
-
- void Concat( char *str1, char *str2 )
- /*****************************
- * Append string 2 to the end of
- * string 1. Both strings are
- * pascal-format strings.
- *
- * str1 must be large enough to hold
- * the new string and is assumed to
- * be of Type Str255 (a pascal string)
- *****************************/
- {
- BlockMove( str2 + 1, str1 + str1[0] + 1, (long)str2[0]);
- str1[0] += str2[0];
- }
-
- pascal void main( XCmdPtr pp )
- /**************************************
- * MAIN ENTRYP POINT FOR THIS XCMD
- *
- * params[0] = the name of the window
- * params[1] = the rect of the window (left,top,right,bottom)
- * params[2] = the window style (dBoxProc, documentProc, palette)
- **************************************/
- {
- Handle answer = NIL;
- char *str;
- long len;
- WindowPtr wind;
- TEHandle hTE;
- Rect bounds;
- short style = documentProc;
- char title[32];
- char temp[64]; /* no need to hog the stack here */
- long dlgID = 0;
-
- pp->returnValue = NIL;
-
- if( pp->paramCount < 0 ){ /* Have an event for one of our windows */
- HandleHCEvent( pp );
- return;
- }
-
- if (pp->paramCount == 1){
- if ( **(pp->params[0]) == '!' ){
- pp->returnValue = PASTOZERO(pp,"\pxwindoid XCMD, version 1.1, ©1991, Donald Koscheka");
- return;
- }
-
- if ( **(pp->params[0]) == '?' ){
- pp->returnValue = PASTOZERO(pp,"\pxwindoid name,rect,style");
- return;
- }
- }
-
- /* if we get this far, the caller must be creating a new window */
- title[0] = 0; /* the default name */
- Concat( title, "\pUntitled");
- if( pp->params[0] ){
- HLock( pp->params[0] );
- ZEROTOPAS( pp, *(pp->params[0]), &title );
- HUnlock( pp->params[0] );
- }
-
- /* the default rectangle if one not specified */
- bounds.top = bounds.left = 0;
- bounds.bottom = 200;
- bounds.right = 300;
- if( pp->params[1] ){
- HLock( pp->params[1] );
- ZEROTOPAS( pp, *(pp->params[1]), &temp );
- STRTORECT( pp, temp, &bounds );
- HUnlock( pp->params[1] );
- }
-
- if( pp->params[2] ){
- HLock( pp->params[2] );
- ZEROTOPAS( pp, *(pp->params[2]), &temp );
-
- /* the poor man's parser */
- if( STRINGEQUAL( pp, temp, "\pDOCUMENTPROC" )) style = documentProc;
- if( STRINGEQUAL( pp, temp, "\pDBOXPROC" )) style = dBoxProc;
- if( STRINGEQUAL( pp, temp, "\pPALETTE" )) style = palette;
- HUnlock( pp->params[2] );
- }
-
- /* these callback will bomb if window is not valid */
- XWALWAYSMOVEHIGH( pp, wind, TRUE );
- XWHASINTERRUPTCODE( pp, wind, TRUE );
-
- if( style == dBoxProc ){
- GrafPtr oldPort;
- short itemHit;
- Handle items;
-
- if( pp->params[3] ){
- HLock( pp->params[3] );
- ZEROTOPAS( pp, *(pp->params[3]), &temp );
- dlgID = STRTONUM( pp, temp );
- HUnlock( pp->params[3] );
- }
-
- items = GetResource( 'DITL', dlgID );
- DetachResource( items );
- wind = NewDialog( NIL, &bounds, title, FALSE, dBoxProc,-1L,FALSE,0L, items );
- CenterWindow( wind, TRUE );
- GetPort( &oldPort );
- SetPort( wind );
- ShowWindow( wind );
-
- do{
- ModalDialog( modalFilter, &itemHit );
- }while( itemHit != OK );
-
- HideWindow( wind );
- DisposDialog( wind );
- SetPort( oldPort );
- }
- else{
- wind = NEWXWINDOW( pp, &bounds, title, FALSE, style,
- FALSE, style==palette);
- CenterWindow( wind, TRUE );
- }
- }
-
- pascal Boolean modalFilter( DialogPtr dlg, EventRecord *evt, short *itemhit )
- /************************************
- * general filter proc, accepts return and
- * enter as ok and hilites the ok button.
- *
- * the ok button is always item 1.
- *
- * Notice that ModalDialog always accesses
- * this routine via a pointer. If your
- * code implemented modalDialog in HandleHCEvent
- * then you will need to make sure that
- * XWHasInterrupt is set to true.
- ************************************/
- {
- int thenum;
- Handle theitem;
- Rect thebox;
- char cc;
-
- short iTyp;
- Handle iHdl;
- Rect iBox;
- ControlHandle okbutn;
-
- switch( evt->what ){
- case keyDown:
- cc = (char)evt->message & charCodeMask;
- GetDItem( dlg, OK, &iTyp, &okbutn, &iBox);
- if( (*okbutn)->contrlHilite != 255 ){
- SetCtlValue( okbutn, 1 );
- if(cc == CR || cc == ETX ){
- *itemhit = OK;
- return TRUE;
- }
- }
- break;
-
- case updateEvt:
- GetDItem( dlg, OK, &iTyp, &okbutn, &iBox);
- if( (*okbutn)->contrlHilite != 255 ){
- PenSize(3,3);
- InsetRect(&iBox,-4,-4);
- FrameRoundRect(&iBox,16,16);
- PenNormal();
- }
- break;
- }/* event switch */
-
- return FALSE;
- }
-
- pascal void HandleHCEvent( XCmdPtr pp )
- /**********************************
- * Handle events in our xWindows
- * returns true if the event was handled ok
- *
- **********************************/
- {
- XWEventInfoPtr ip = pp->params[0];
- WindowPtr whichWindow;
- short windoPart;
- TEHandle hTE;
- Rect bounds;
- Point hit;
- char theKey;
- GrafPtr oldPort;
- short extend;
-
- pp->passFlag = TRUE; /* seems to be more often the case */
-
- switch( ip->event.what ){
- case mouseDown:
- windoPart = FindWindow( ip->event.where, &whichWindow );
-
- if( whichWindow )
- switch ( windoPart ){
- case inGoAway:
- if (TrackGoAway( whichWindow, ip->event.where) ){
- CLOSEXWINDOW( pp,whichWindow );
- pp->passFlag = FALSE;
- }
- break;
-
- case inDrag:
- /* handled by hypercard */
- break;
-
- case inGrow:
- break;
-
- case inContent:
- if (whichWindow == FrontWindow() ){
- GetPort( &oldPort );
- SetPort( ip->eventWindow );
-
- SetPort( oldPort );
- }else
- SelectWindow( whichWindow );
-
- pp->passFlag = FALSE;
- break;
-
- default:
- break;
- }/* window part */
- break;
-
- case mouseUp:
- break;
-
- case keyDown:
- case autoKey:
- /* the command key will be handled by hypercard */
- GetPort( &oldPort );
- SetPort( ip->eventWindow );
- theKey = ip->event.message & 0xFF;
-
- SetPort( oldPort );
- pp->passFlag = FALSE;
- break;
-
- case activateEvt:
- if ( ip->event.modifiers & activeFlag )
- BEGINXWEDIT( pp, ip->eventWindow );
- else
- ENDXWEDIT( pp, ip->eventWindow );
- break;
-
- case updateEvt:
- /* hypercard converts dialogs to 0x14 kind? */
- if(((WindowPeek)(ip->eventWindow))->windowKind != 0x14) {
- BeginUpdate( ip->eventWindow );
- EndUpdate( ip->eventWindow );
- }
- break;
-
- case app4Evt:
- {
- unsigned char *evtType = &(ip->event.message);
-
- switch( *evtType ){
- case MouseMovedEvt:
- break;
-
- case SuspendResumeEvt:
- break;
- }
- }
- break;
-
- /****************************************/
- /* THE HYPERCARD EVENTS */
- /****************************************/
- case xOpenEvt:
- SetPort( ip->eventWindow );
- ShowWindow( ip->eventWindow );
- break;
-
- case xCloseEvt:
- HideWindow( ip->eventWindow );
- break;
-
- case xGiveUpEditEvt:
- break;
-
- case xEditUndo:
- break;
-
- case xEditCut:
- break;
-
- case xEditCopy:
- break;
-
- case xEditPaste:
- break;
-
- case xEditClear:
- break;
-
- default:
- GetPort( &oldPort );
- SetPort( ip->eventWindow );
- GetMouse( &hit );
-
- pp->passFlag = FALSE;
- SetPort( oldPort );
- }/* switch theEvent->what */
- }
-
-
-
-